from django.db import models
from django.contrib.auth.models import User
from django.core.validators import URLValidator
from cmdb.models import Host
import json


class ZabbixServer(models.Model):
    """Zabbix服务器配置"""
    name = models.CharField(max_length=100, unique=True, verbose_name="服务器名称")
    description = models.TextField(blank=True, verbose_name="描述")

    # 连接配置
    url = models.URLField(verbose_name="Zabbix URL", help_text="例如: http://10.0.0.201/zabbix")
    username = models.CharField(max_length=100, verbose_name="用户名")
    password = models.CharField(max_length=255, verbose_name="密码")
    api_token = models.CharField(max_length=500, blank=True, verbose_name="API Token",
                                help_text="可选，如果设置则优先使用Token认证")

    # 状态配置
    is_active = models.BooleanField(default=True, verbose_name="是否启用")
    is_default = models.BooleanField(default=False, verbose_name="是否为默认服务器")

    # 连接状态
    CONNECTION_STATUS_CHOICES = [
        ('unknown', '未知'),
        ('connected', '已连接'),
        ('disconnected', '连接失败'),
        ('error', '错误'),
    ]
    connection_status = models.CharField(max_length=20, choices=CONNECTION_STATUS_CHOICES,
                                       default='unknown', verbose_name="连接状态")
    last_check_time = models.DateTimeField(null=True, blank=True, verbose_name="最后检查时间")
    error_message = models.TextField(blank=True, verbose_name="错误信息")

    # 统计信息
    total_hosts = models.IntegerField(default=0, verbose_name="主机总数")
    total_items = models.IntegerField(default=0, verbose_name="监控项总数")
    total_triggers = models.IntegerField(default=0, verbose_name="触发器总数")

    # 时间戳
    created_at = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
    updated_at = models.DateTimeField(auto_now=True, verbose_name="更新时间")
    created_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, verbose_name="创建者")

    class Meta:
        verbose_name = "Zabbix服务器"
        verbose_name_plural = "Zabbix服务器"
        ordering = ['-is_default', '-created_at']

    def __str__(self):
        return f"{self.name} ({self.url})"

    def save(self, *args, **kwargs):
        # 确保只有一个默认服务器
        if self.is_default:
            ZabbixServer.objects.filter(is_default=True).update(is_default=False)
        super().save(*args, **kwargs)


# GrafanaServer模型已移除，使用Zabbix原生仪表板功能


class MonitoringHost(models.Model):
    """监控主机关联"""
    host = models.OneToOneField(Host, on_delete=models.CASCADE, verbose_name="关联主机")
    zabbix_server = models.ForeignKey(ZabbixServer, on_delete=models.CASCADE, verbose_name="Zabbix服务器")

    # Zabbix中的信息
    zabbix_host_id = models.CharField(max_length=50, blank=True, verbose_name="Zabbix主机ID")
    zabbix_host_name = models.CharField(max_length=100, blank=True, verbose_name="Zabbix主机名")

    # 监控状态
    MONITORING_STATUS_CHOICES = [
        ('not_monitored', '未监控'),
        ('monitoring', '监控中'),
        ('disabled', '已禁用'),
        ('error', '错误'),
    ]
    monitoring_status = models.CharField(max_length=20, choices=MONITORING_STATUS_CHOICES,
                                       default='not_monitored', verbose_name="监控状态")

    # 监控模板
    applied_templates = models.JSONField(default=list, verbose_name="应用的模板")

    # 状态信息
    last_check_time = models.DateTimeField(null=True, blank=True, verbose_name="最后检查时间")
    availability = models.CharField(max_length=20, blank=True, verbose_name="可用性状态")
    error_message = models.TextField(blank=True, verbose_name="错误信息")

    # 统计信息
    total_items = models.IntegerField(default=0, verbose_name="监控项数量")
    total_triggers = models.IntegerField(default=0, verbose_name="触发器数量")
    active_alerts = models.IntegerField(default=0, verbose_name="活跃告警数量")

    # 时间戳
    created_at = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
    updated_at = models.DateTimeField(auto_now=True, verbose_name="更新时间")

    class Meta:
        verbose_name = "监控主机"
        verbose_name_plural = "监控主机"
        unique_together = ['host', 'zabbix_server']

    def __str__(self):
        return f"{self.host.hostname} -> {self.zabbix_server.name}"


class MonitoringAlert(models.Model):
    """监控告警"""
    # 基本信息
    title = models.CharField(max_length=200, verbose_name="告警标题")
    description = models.TextField(blank=True, verbose_name="告警描述")

    # 关联信息
    host = models.ForeignKey(Host, on_delete=models.CASCADE, null=True, blank=True, verbose_name="关联主机")
    zabbix_server = models.ForeignKey(ZabbixServer, on_delete=models.CASCADE, verbose_name="Zabbix服务器")

    # Zabbix信息
    zabbix_event_id = models.CharField(max_length=50, verbose_name="Zabbix事件ID")
    zabbix_trigger_id = models.CharField(max_length=50, verbose_name="Zabbix触发器ID")

    # 告警级别
    SEVERITY_CHOICES = [
        ('not_classified', '未分类'),
        ('information', '信息'),
        ('warning', '警告'),
        ('average', '一般严重'),
        ('high', '严重'),
        ('disaster', '灾难'),
    ]
    severity = models.CharField(max_length=20, choices=SEVERITY_CHOICES, verbose_name="严重程度")

    # 告警状态
    STATUS_CHOICES = [
        ('active', '活跃'),
        ('acknowledged', '已确认'),
        ('resolved', '已解决'),
        ('suppressed', '已抑制'),
    ]
    status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='active', verbose_name="状态")

    # 时间信息
    event_time = models.DateTimeField(verbose_name="事件时间")
    acknowledged_time = models.DateTimeField(null=True, blank=True, verbose_name="确认时间")
    resolved_time = models.DateTimeField(null=True, blank=True, verbose_name="解决时间")

    # 处理信息
    acknowledged_by = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True,
                                      related_name='acknowledged_alerts', verbose_name="确认人")
    acknowledgment_message = models.TextField(blank=True, verbose_name="确认消息")

    # 额外数据
    raw_data = models.JSONField(default=dict, verbose_name="原始数据")

    # 时间戳
    created_at = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
    updated_at = models.DateTimeField(auto_now=True, verbose_name="更新时间")

    class Meta:
        verbose_name = "监控告警"
        verbose_name_plural = "监控告警"
        ordering = ['-event_time']
        unique_together = ['zabbix_server', 'zabbix_event_id']

    def __str__(self):
        host_name = self.host.hostname if self.host else "未知主机"
        return f"{self.title} - {host_name}"


class AlertRule(models.Model):
    """告警规则"""
    SEVERITY_CHOICES = [
        ('low', '轻微'),
        ('medium', '一般'),
        ('high', '严重'),
        ('critical', '紧急'),
    ]

    CONDITION_CHOICES = [
        ('>', '大于'),
        ('>=', '大于等于'),
        ('<', '小于'),
        ('<=', '小于等于'),
        ('=', '等于'),
        ('!=', '不等于'),
    ]

    name = models.CharField(max_length=200, verbose_name='规则名称')
    description = models.TextField(blank=True, verbose_name='规则描述')

    # 监控项配置
    template_id = models.CharField(max_length=50, blank=True, null=True, verbose_name='模板ID')
    metric_name = models.CharField(max_length=200, verbose_name='监控项名称')
    condition = models.CharField(max_length=10, choices=CONDITION_CHOICES, verbose_name='条件')
    threshold_value = models.FloatField(verbose_name='阈值')

    # 告警配置
    severity = models.CharField(max_length=20, choices=SEVERITY_CHOICES, default='medium', verbose_name='严重级别')
    duration = models.IntegerField(default=300, verbose_name='持续时间(秒)')

    # 关联配置
    zabbix_server = models.ForeignKey(ZabbixServer, on_delete=models.CASCADE, verbose_name='Zabbix服务器')
    host_groups = models.ManyToManyField('HostGroup', blank=True, verbose_name='主机组')

    # 通知配置
    enable_notification = models.BooleanField(default=True, verbose_name='启用通知')
    notification_channels = models.ManyToManyField('NotificationChannel', blank=True, verbose_name='通知渠道')

    # 状态字段
    is_active = models.BooleanField(default=True, verbose_name='是否启用')
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
    updated_at = models.DateTimeField(auto_now=True, verbose_name='更新时间')
    created_by = models.ForeignKey('auth.User', on_delete=models.SET_NULL, null=True, verbose_name='创建者')

    class Meta:
        verbose_name = '告警规则'
        verbose_name_plural = '告警规则'
        ordering = ['-created_at']

    def __str__(self):
        return f"{self.name} - {self.get_severity_display()}"


class HostGroup(models.Model):
    """主机组"""
    name = models.CharField(max_length=200, unique=True, verbose_name='组名')
    description = models.TextField(blank=True, verbose_name='描述')
    zabbix_server = models.ForeignKey(ZabbixServer, on_delete=models.CASCADE, verbose_name='Zabbix服务器')
    zabbix_group_id = models.CharField(max_length=50, blank=True, verbose_name='Zabbix组ID')

    created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
    updated_at = models.DateTimeField(auto_now=True, verbose_name='更新时间')

    class Meta:
        verbose_name = '主机组'
        verbose_name_plural = '主机组'
        unique_together = ['name', 'zabbix_server']

    def __str__(self):
        return self.name


class NotificationChannel(models.Model):
    """通知渠道"""
    CHANNEL_TYPES = [
        ('email', '邮件'),
        ('sms', '短信'),
        ('webhook', 'Webhook'),
        ('dingtalk', '钉钉'),
        ('wechat', '企业微信'),
        ('slack', 'Slack'),
    ]

    name = models.CharField(max_length=200, verbose_name='渠道名称')
    channel_type = models.CharField(max_length=20, choices=CHANNEL_TYPES, verbose_name='渠道类型')

    # 配置信息（JSON格式存储不同类型的配置）
    config = models.JSONField(default=dict, verbose_name='配置信息')

    # 状态字段
    is_active = models.BooleanField(default=True, verbose_name='是否启用')
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
    updated_at = models.DateTimeField(auto_now=True, verbose_name='更新时间')

    class Meta:
        verbose_name = '通知渠道'
        verbose_name_plural = '通知渠道'

    def __str__(self):
        return f"{self.name} ({self.get_channel_type_display()})"


class AlertNotification(models.Model):
    """告警通知记录"""
    STATUS_CHOICES = [
        ('pending', '待发送'),
        ('sent', '已发送'),
        ('failed', '发送失败'),
        ('retry', '重试中'),
    ]

    alert = models.ForeignKey(MonitoringAlert, on_delete=models.CASCADE, verbose_name='告警')
    channel = models.ForeignKey(NotificationChannel, on_delete=models.CASCADE, verbose_name='通知渠道')

    # 通知内容
    subject = models.CharField(max_length=500, verbose_name='主题')
    content = models.TextField(verbose_name='内容')

    # 发送状态
    status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='pending', verbose_name='状态')
    sent_at = models.DateTimeField(null=True, blank=True, verbose_name='发送时间')
    error_message = models.TextField(blank=True, verbose_name='错误信息')
    retry_count = models.IntegerField(default=0, verbose_name='重试次数')

    created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')

    class Meta:
        verbose_name = '告警通知'
        verbose_name_plural = '告警通知'
        ordering = ['-created_at']

    def __str__(self):
        return f"{self.alert.title} -> {self.channel.name}"


class EmailConfig(models.Model):
    """邮件配置"""
    name = models.CharField(max_length=100, verbose_name='配置名称')
    smtp_server = models.CharField(max_length=200, verbose_name='SMTP服务器')
    smtp_port = models.IntegerField(default=587, verbose_name='SMTP端口')
    username = models.CharField(max_length=200, verbose_name='用户名')
    password = models.CharField(max_length=200, verbose_name='密码/授权码')
    from_email = models.EmailField(verbose_name='发件人邮箱')
    default_recipients = models.TextField(blank=True, verbose_name='默认收件人', help_text='多个邮箱用逗号分隔')
    use_tls = models.BooleanField(default=True, verbose_name='使用TLS')
    use_ssl = models.BooleanField(default=False, verbose_name='使用SSL')
    is_default = models.BooleanField(default=False, verbose_name='默认配置')
    is_active = models.BooleanField(default=True, verbose_name='是否启用')
    created_by = models.ForeignKey('auth.User', on_delete=models.CASCADE, verbose_name='创建者')
    created_at = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
    updated_at = models.DateTimeField(auto_now=True, verbose_name='更新时间')

    class Meta:
        db_table = 'monitoring_email_config'
        verbose_name = '邮件配置'
        verbose_name_plural = '邮件配置'
        ordering = ['-created_at']

    def __str__(self):
        return f"{self.name} ({self.from_email})"

    def save(self, *args, **kwargs):
        # 如果设置为默认配置，取消其他默认配置
        if self.is_default:
            EmailConfig.objects.filter(is_default=True).update(is_default=False)
        super().save(*args, **kwargs)
